#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*#include "sockets.h"*/

#include "ssh.h"
#include "winsock.h"
/*#include "def.h"
#include "sshif.h"
#include "syslogif.h"*/

#include "bn.h"
#include "bn_lcl.h"
#include "openssh.h"

static char *readFilename=NULL, *writeFilename=NULL;
static int hostkeyfileWritten = FALSE;

/*#define dprintf(a) fprintf a*/
#define dprintf(a)

char *verify_ssh_host_key2(char *host, struct RSAKey *key )
{
  BIGNUM *remoteExponent,*remoteModulus,*storedExponent,*storedModulus;
  unsigned char *puttyModulus,*puttyExponent,*puttyModulusReversed,*puttyExponentReversed;
  char *s;
  int i=0,puttyModulusLength=0,puttyExponentLength=0;
  HostStatus status;
  char *message=NULL;

  dprintf((stderr,"verify_ssh_host_key: assuming host %s is valid - haven't checked key",host));
  dprintf((stderr,"verify_ssh_host_key: host key is: %p: ",key));
/*  dprintf(stderr,,key,sizeof(struct RSAKey),(int) key);
  xsyslog_logdata(SYSLOG_FILE,LOG_DEBUG_HIGH,key->modulus,key->bytes,(int) key->modulus);
  xsyslog_logdata(SYSLOG_FILE,LOG_DEBUG_HIGH,key->exponent,key->bytes,(int) key->exponent);*/

  remoteExponent = BN_new();
  remoteModulus = BN_new();
  storedExponent = BN_new();
  storedModulus = BN_new();
  if ((remoteExponent == NULL) || (remoteModulus == NULL))
    return;
  if ((storedExponent == NULL) || (storedModulus == NULL))
    return;

  dprintf((stderr,"done bn_news\n"));
  puttyModulus = (unsigned char *) key->modulus;
  puttyExponent = (unsigned char *) key->exponent;
  dprintf((stderr,"pm = %p, pe = %p, pml = %d, pel = %d\n",puttyModulus,puttyExponent,puttyModulusLength,puttyExponentLength));
  puttyModulusLength = 2*((unsigned short *)(puttyModulus))[0];
  puttyExponentLength = 2*((unsigned short *)(puttyExponent))[0];

  /* PuTTY's host keys have bytes in the wrong order for BN functions */
  puttyModulusReversed = malloc(puttyModulusLength);
  puttyExponentReversed = malloc(puttyExponentLength);
  if ((puttyModulusReversed == NULL) || (puttyExponentReversed == NULL))
    return;

  for (i=0; i<puttyModulusLength; i++)
  {
    puttyModulusReversed[i] = puttyModulus[puttyModulusLength-i-1+2];
  }

/*  xsyslog_logdata(SYSLOG_FILE,LOG_DEBUG_LOW,puttyModulusReversed,puttyModulusLength,(int) puttyModulusReversed);*/
  dprintf((stderr,"reversed mod\n"));
  BN_bin2bn(puttyModulusReversed,puttyModulusLength,remoteModulus);
  free(puttyModulusReversed);

  for (i=0; i<puttyExponentLength; i++)
  {
    puttyExponentReversed[i] = puttyExponent[puttyExponentLength-i-1+2];
  }

  dprintf((stderr,"reverserd exp\n"));
  BN_bin2bn(puttyExponentReversed,puttyExponentLength,remoteExponent);
  free(puttyExponentReversed);

  s=BN_bn2dec(remoteModulus);
  dprintf((stderr,"modulus is %s",s));
  free(s);
  s=BN_bn2dec(remoteExponent);
  dprintf((stderr,"exponent is %s",s));
  free(s);

  status = check_host_in_hostfile("<pscp$Choices>.Crypto.SSH.KnownHosts",host,
    remoteExponent,remoteModulus,storedExponent,storedModulus);
/*  xsyslogf_irq(SYSLOG_FILE,LOG_CONNECTION_LOW,"host key status %d",status);*/

  switch (status)
  {
    case HOST_OK:
      message="\n\rRemote host are who they claim to be... good!\n\r";
      break;
    case HOST_NEW:

      if (add_host_to_hostfile("<pscp$Choices>.Crypto.SSH.KnownHosts",host,remoteExponent,remoteModulus))
      {
        message="\n\r*** Don't recognise this remote host - adding to local list of known hosts\n\r*** Make sure they are who they claim to be...\n\r";
      }
      else
      {
        message="\n\r*** Don't recognise this remote host - file error in adding to list of known hosts\n\r*** Make sure they are who they claim to be...\n\r";
      }
      break;
    case HOST_CHANGED:
      message="\n\r*** SECURITY ALERT: Remote host's key differs from that stored locally.\n\r***This may be a result of a security attack, or sloppy system administration\n\r*** Be careful when continuing!\n\r";
  }

  BN_free(remoteModulus);
  BN_free(remoteExponent);
  BN_free(storedModulus);
  BN_free(storedExponent);

  return message;
}

void verify_ssh_host_key(char *host, struct RSAKey *key)
{
  fprintf(stderr,"%s",verify_ssh_host_key2(host,key));
  return;
}

#if 0
void verify_ssh_host_key2(WChar *host, struct RSAKey *key) {
  char line[4096];
  char *token;

  if (readFilename == NULL)
    choices_return_filename(&readFilename,&writeFilename);

  token = choices_search_for_token(readFilename,host,line,sizeof(line));

  if (!token)
  {
    /* warn about adding */
    choices_add_token(readFilename,writeFilename,host,
  }

  return;
}
#endif
